package com.luoyuanxiangvip.admin.core.shiro;

import com.luoyuanxiangvip.admin.core.jwt.JwtToken;
import com.luoyuanxiangvip.common.constant.Constant;
import com.luoyuanxiangvip.common.exception.ExpiredException;
import com.luoyuanxiangvip.common.exception.InvalidException;
import com.luoyuanxiangvip.common.exception.PasswordException;
import com.luoyuanxiangvip.core.entity.SysUser;
import com.luoyuanxiangvip.core.service.ISysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

/**
 * <p>
 * 用户认证
 * </p>
 *
 * @author luoyuanxiang <p>luoyuanxiangvip.com</p>
 * @since 2019/5/26 18:49
 */
public class UserRealm extends AuthorizingRealm {

    @Resource
    private JwtToken jwtToken;
    @Resource
    private ISysUserService iSysUserService;
    @Resource
    private HttpSession session;

    /**
     * 大坑！，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof AuthToken;
    }

    /**
     * 权限认证
     *
     * @param principals pr
     * @return auth
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return new SimpleAuthorizationInfo();
    }

    /**
     * 登陆认证
     *
     * @param authenticationToken token
     * @return auth
     * @throws AuthenticationException auth
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();
        if (jwtToken.parseToken(token)) {
            throw new AuthenticationException(new InvalidException("token无效！"));
        }
        String userName = jwtToken.getUsernameFromToken(token);
        SysUser byUserName = iSysUserService.findByUserName(userName);
        if (byUserName == null) {
            throw new AuthenticationException("用户不存在！");
        }
        if (!byUserName.getPassword().equals(jwtToken.getMd5KeyFromToken(token))) {
            throw new AuthenticationException(new PasswordException("密码错误!"));
        }
        if (jwtToken.isTokenExpired(token)) {
            throw new AuthenticationException(new ExpiredException("token过期!"));
        }
        session.setAttribute(Constant.USER, byUserName);
        return new SimpleAuthenticationInfo(token, token, getName());
    }
}
